package com.hollycrm.hollysqm.job.synchro.dao;

import java.sql.CallableStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.CallableStatementCallback;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import oracle.jdbc.internal.OracleTypes;

/**
 * 数据入库DAO
 * @author jianglong
 * @date 2017年3月9日 上午10:53:01
 */
@Repository
public class SynchroV8DataFileJobDao {

	private final Logger log = LoggerFactory.getLogger(getClass());

	private final static int BAT_SIZE=50;
	private final static String SPLIT_CHAR="|";
	private final static String SPLIT_CHAR2="\\|";
	
	@Autowired
    private JdbcTemplate jdbc;
	
	/**
	 * 插入解析后的数据到表中
	 * 录音记录信息数据
	 * @param areaCode	省份代码
	 * @param insertSql	执行SQL
	 * @param dataList	数据集
	 * @throws Exception
	 */
	public void insertRecoinfoData(String areaCode,String insertSql,List<String> dataList) throws Exception {		
		String data;
		String [] datas;
		int size=dataList.size();		
		List<Object[]> params = new ArrayList<>(BAT_SIZE);
		int i=0;
		Object[] objs=null;
		for (;i<size;i++){
			data=dataList.get(i);
			if (!StringUtils.isNotBlank(data) || !data.contains(SPLIT_CHAR)){
				continue;
			}
			datas=data.split(SPLIT_CHAR2);//每行的数据内容按|分隔开			
			if (datas.length<13){
				continue;
			}
			objs=new Object[14];
			System.arraycopy(datas, 0, objs, 0, datas.length);
			objs[13]=areaCode;	
			params.add(objs);
			if ((i+1)%BAT_SIZE==0){//每50条记录批量插入一次
				jdbc.batchUpdate(insertSql, params);
				params.clear();				
			}
		}
		//不足50的，在结尾时也批量插入
		if (params.size()>0){
			jdbc.batchUpdate(insertSql, params);
		}
	}
		
	/**
	 * 插入解析后的数据到表中
	 * 服务请求数据：用户拨打10010，通过座席代表获取人工服务，在座席代表服务后，系统会生成服务请求数据
	 * @param areaCode	省份代码
	 * @param insertSql	执行SQL
	 * @param dataList	数据集
	 * @throws Exception
	 */
	public void insertSerequestfoData(String areaCode,String insertSql,List<String> dataList) throws Exception {		
		String data;
		String [] datas;
		int size=dataList.size();		
		List<Object[]> params = new ArrayList<>(BAT_SIZE);
		int i=0;
		Object[] objs=null;
		for (;i<size;i++){
			data=dataList.get(i);
			if (!StringUtils.isNotBlank(data) || !data.contains(SPLIT_CHAR)){
				continue;
			}
			datas=data.split(SPLIT_CHAR2);//每行的数据内容按|分隔开			
			if (datas.length<6){
				continue;
			}
			objs=new Object[7];			
			System.arraycopy(datas, 0, objs, 0, datas.length);
			objs[6]=areaCode;
			
			params.add(objs);
			if ((i+1)%BAT_SIZE==0){//每50条记录批量插入一次
				jdbc.batchUpdate(insertSql, params);
				params.clear();				
			}
		}
		//不足50的，在结尾时也批量插入
		if (params.size()>0){
			jdbc.batchUpdate(insertSql, params);
		}
	}
	
	/**
	 * 插入解析后的数据到表中
	 * 客户接触记录数据：用户拨打10010，通过座席代表获得人工服务中，系统会产生客户接触记录数据
	 * @param areaCode	省份代码
	 * @param insertSql	执行SQL
	 * @param dataList	数据集
	 * @throws Exception
	 */
	public void insertCustcontinfoData(String areaCode,String insertSql,List<String> dataList) throws Exception {		
		String data;
		String [] datas;
		int size=dataList.size();		
		List<Object[]> params = new ArrayList<>(BAT_SIZE);
		int i=0;
		Object[] objs=null;
		for (;i<size;i++){
			data=dataList.get(i);
			if (!StringUtils.isNotBlank(data) || !data.contains(SPLIT_CHAR)){
				continue;
			}
			datas=data.split(SPLIT_CHAR2);//每行的数据内容按|分隔开			
			if (datas.length<22){
				continue;
			}
			objs=new Object[23];
			System.arraycopy(datas, 0, objs, 0, datas.length);
			objs[22]=areaCode;
			
			params.add(objs);
			if ((i+1)%BAT_SIZE==0){//每50条记录批量插入一次
				jdbc.batchUpdate(insertSql, params);
				params.clear();				
			}
		}
		//不足50的，在结尾时也批量插入
		if (params.size()>0){
			jdbc.batchUpdate(insertSql, params);
		}
	}
	
	/**
	 * 执行存储过程，将三张表的数据合并到一张大表中
	 * @param executeDate 执行时间：2015111111(到小时)
	 * @param areaCode 省份编码
	 * @throws Exception
	 */	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void executePrc(final String executeDate,final String areaCode) throws Exception{		
		String sql = "{call PKG_POC_COLLECT_DATA.PRC_INSERT_CUSTCONTINFO(?,?,?)}";// 调用的存储过程
		Object obj=jdbc.execute(sql,new CallableStatementCallback(){
	        public Object doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException { 	        	   	                 
	            cs.setString(1, executeDate);// 设置输入参数的值:执行时间
	            cs.setString(2, areaCode);// 设置输入参数的值 :省份编码
	            cs.registerOutParameter(3,OracleTypes.NUMBER);// 注册输出参数的类型   
	            cs.execute(); 
	            return cs.getInt(3);
	        }
	    }); 
		int count=((Integer)obj).intValue();
		log.info("PKG_POC_COLLECT_DATA.PRC_INSERT_CUSTCONTINFO存储过程已成功执行三张表的数据合并，受影响行："+count);
	}
	
}
